package com.example.spring.framework.aop.aspect;

import com.example.spring.framework.util.ObjectUtils;

import java.lang.reflect.Method;

/**
 * @Classname AbstractAspectAdvice
 * @Date 2019/4/22 23:46
 * @Author admin
 * @Description TODO
 */
public abstract class AbstractAspectJAdvice implements Advice {

    private Method aspectMethod;

    private Object aspectTarget;

    public AbstractAspectJAdvice(Method aspectMethod, Object aspectTarget) {
        this.aspectMethod = aspectMethod;
        this.aspectTarget = aspectTarget;
    }

    public Object invokeAdviceMethod(JoinPoint joinPoint, Object returnValue, Throwable tx) throws Exception {
        Class<?>[] paramTypes = this.aspectMethod.getParameterTypes();
        if (ObjectUtils.isEmpty(paramTypes)) {
            return this.aspectMethod.invoke(aspectTarget);
        } else {
            Object[] args = new Object[paramTypes.length];
            for (int i = 0; i < paramTypes.length; i++) {
                if (paramTypes[i] == JoinPoint.class) {
                    args[i] = joinPoint;
                } else if (paramTypes[i] == Throwable.class) {
                    args[i] = tx;
                } else if (paramTypes[i] == Object.class) {
                    args[i] = returnValue;
                }
            }
            return this.aspectMethod.invoke(this.aspectTarget, args);
        }
    }
}